package com.zmn.plat.business.impl.product.tariff.item.city.price;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.plat.business.interfaces.product.tariff.item.city.price.ProductTariffItemCityPriceBService;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.model.entity.product.tariff.item.city.price.ProductTariffItemCityPrice;
import com.zmn.plat.model.entity.product.tariff.item.city.price.ProductTariffItemCityPriceQuery;
import com.zmn.plat.model.entity.service.tariff.citygroup.item.ServiceTariffCityGroupItem;
import com.zmn.plat.model.vo.area.ProvinceCityVO;
import com.zmn.plat.model.vo.product.tariff.item.city.price.ProductTariffItemCityPriceBatchGroupVo;
import com.zmn.plat.model.vo.product.tariff.item.city.price.ProductTariffItemCityPriceBatchVo;
import com.zmn.plat.model.vo.product.tariff.item.city.price.ProductTariffItemCityPriceGroupVo;
import com.zmn.plat.services.interfaces.product.tariff.item.city.price.ProductTariffItemCityPriceService;
import com.zmn.plat.services.interfaces.service.tariff.citygroup.item.ServiceTariffCityGroupItemService;

/**
 * 类描述:
 *
 * @author linfeng
 * @since 2019/11/28/11:14
 */
@Service
public class ProductTariffItemCityPriceBServiceImpl implements ProductTariffItemCityPriceBService {
    private Logger logger = LoggerFactory.getLogger(ProductTariffItemCityPriceBServiceImpl.class);

    @Resource
    ProductTariffItemCityPriceService productFaultItemCityPriceService;
    @Resource
    ServiceTariffCityGroupItemService faultCityGroupItemService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchAddCityPrice(String mcStaffName, ProductTariffItemCityPriceBatchVo productFaultItemCityPriceBatchVo) {
        Date now = DateUtil.getNow();

        List<ProvinceCityVO> provinceCityVOS = productFaultItemCityPriceBatchVo.getProvinceCityVOS();
        List<Integer> cityIdList = provinceCityVOS.stream().map(ProvinceCityVO::getCityId).collect(Collectors.toList());
        ProductTariffItemCityPriceQuery query = new ProductTariffItemCityPriceQuery();
        query.setProductId(productFaultItemCityPriceBatchVo.getProductId());
        query.setTariffId(productFaultItemCityPriceBatchVo.getTariffId());
        query.setItemId(productFaultItemCityPriceBatchVo.getItemId());
        query.setCityIds(cityIdList);
        List<ProductTariffItemCityPrice> dbItems = productFaultItemCityPriceService.listByQuery(query);
        Map<Integer, ProductTariffItemCityPrice> map = new HashMap<>(dbItems.size());
        for (int i = 0; i < dbItems.size(); i++) {
            map.put(dbItems.get(i).getCityId(), dbItems.get(i));
        }

        List<Integer> updateIdList = dbItems.stream().map(ProductTariffItemCityPrice::getRelateId).collect(Collectors.toList());
        List<ProductTariffItemCityPrice> insertList = new ArrayList<>(cityIdList.size() - dbItems.size());

        ProvinceCityVO provinceCityVO;
        ProductTariffItemCityPrice productFaultItemCityPrice;
        for (int i = 0; i < provinceCityVOS.size(); i++) {
            provinceCityVO = provinceCityVOS.get(i);
            if (Objects.isNull(map.get(provinceCityVO.getCityId()))) {
                productFaultItemCityPrice = new ProductTariffItemCityPrice();
                productFaultItemCityPrice.setProductId(productFaultItemCityPriceBatchVo.getProductId());
                productFaultItemCityPrice.setTariffId(productFaultItemCityPriceBatchVo.getTariffId());
                productFaultItemCityPrice.setGroupId(productFaultItemCityPriceBatchVo.getGroupId());
                productFaultItemCityPrice.setItemId(productFaultItemCityPriceBatchVo.getItemId());
                productFaultItemCityPrice.setProvinceId(provinceCityVO.getProvinceId());
                productFaultItemCityPrice.setCityId(provinceCityVO.getCityId());
                productFaultItemCityPrice.setPriceStandard(productFaultItemCityPriceBatchVo.getPriceStandard());
                productFaultItemCityPrice.setPrice(productFaultItemCityPriceBatchVo.getPrice());
                productFaultItemCityPrice.setInternalSettlementPrice(productFaultItemCityPriceBatchVo.getInternalSettlementPrice());
                productFaultItemCityPrice.setExternalSettlementPrice(productFaultItemCityPriceBatchVo.getExternalSettlementPrice());
                productFaultItemCityPrice.setNegotiableMaxPrice(productFaultItemCityPriceBatchVo.getNegotiableMaxPrice());
                productFaultItemCityPrice.setNegotiableMinPrice(productFaultItemCityPriceBatchVo.getNegotiableMinPrice());
                productFaultItemCityPrice.setCreater(mcStaffName);
                productFaultItemCityPrice.setCreateTime(now);
                productFaultItemCityPrice.setUpdater(mcStaffName);
                productFaultItemCityPrice.setUpdateTime(now);
                insertList.add(productFaultItemCityPrice);
            }
        }

        if (!CollectionUtils.isEmpty(insertList)) {
            productFaultItemCityPriceService.insertBatch(insertList);
        }

        if (!CollectionUtils.isEmpty(updateIdList)) {
            productFaultItemCityPriceService.updateBatch(updateIdList, productFaultItemCityPriceBatchVo.getPriceStandard(), productFaultItemCityPriceBatchVo.getPrice(),
                productFaultItemCityPriceBatchVo.getInternalSettlementPrice(), productFaultItemCityPriceBatchVo.getExternalSettlementPrice(), productFaultItemCityPriceBatchVo.getNegotiableMaxPrice(),
                productFaultItemCityPriceBatchVo.getNegotiableMinPrice(), mcStaffName, DateUtil.getNow());
        }

        return productFaultItemCityPriceBatchVo.getProductId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchAddCityPriceByCityGroup(String realName, ProductTariffItemCityPriceBatchGroupVo groupVo) {
        // 分组上的价格是一次性的提交过来的，检查合法的分组（至少有一个价格）
        List<ProductTariffItemCityPriceGroupVo> list = groupVo.getGroupList();
        Map<Integer, ProductTariffItemCityPriceGroupVo> cityGroupMap =
            list.stream().filter(e -> isDataValidate(e)).collect(Collectors.toMap(ProductTariffItemCityPriceGroupVo::getGroupId, a -> a, (k1, k2) -> k1));
        if (CollectionUtils.isEmpty(cityGroupMap)) {
            throw new PlatException("请在分组上填写对应的价格，至少保证有一个价格");
        }
        List<Integer> groupIds = new ArrayList<>(cityGroupMap.keySet());
        List<ServiceTariffCityGroupItem> faultCityGroupItems = faultCityGroupItemService.listByGroupIds(groupIds);
        if (CollectionUtils.isEmpty(faultCityGroupItems)) {
            throw new PlatException("所选分组没关联城市，请先关联城市分组的城市");
        }
        // 删除所选的分组下城市中已配置的价格数据
        productFaultItemCityPriceService.deleteByCityGroupIdsAndItemIdAndProductId(groupIds, groupVo.getItemId(), groupVo.getProductId(), groupVo.getTariffId());
        Date now = DateUtil.getNow();
        // 拼装新的数据插入
        List<ProductTariffItemCityPrice> insertList =
            faultCityGroupItems.stream().map(e -> createCityPriceItem(e, groupVo, cityGroupMap.get(e.getGroupId()), realName, now)).collect(Collectors.toList());
        // 删除原有的城市价格，新增新的城市价格
        return productFaultItemCityPriceService.insertBatch(insertList);
    }

    private ProductTariffItemCityPrice createCityPriceItem(ServiceTariffCityGroupItem item, ProductTariffItemCityPriceBatchGroupVo groupVo, ProductTariffItemCityPriceGroupVo itemVo,
        String mcStaffName, Date now) {
        ProductTariffItemCityPrice priceItem = new ProductTariffItemCityPrice();
        priceItem.setItemId(groupVo.getItemId());
        priceItem.setProductId(groupVo.getProductId());
        priceItem.setTariffId(groupVo.getTariffId());
        priceItem.setGroupId(groupVo.getGroupId());
        priceItem.setItemId(groupVo.getItemId());
        priceItem.setProvinceId(item.getProvinceId());
        priceItem.setCityId(item.getCityId());
        priceItem.setPriceStandard(groupVo.getPriceStandard());
        priceItem.setPrice(itemVo.getPrice());
        priceItem.setInternalSettlementPrice(itemVo.getInternalSettlementPrice());
        priceItem.setExternalSettlementPrice(itemVo.getExternalSettlementPrice());
        priceItem.setNegotiableMaxPrice(itemVo.getNegotiableMaxPrice());
        priceItem.setNegotiableMinPrice(itemVo.getNegotiableMinPrice());
        priceItem.setCreater(mcStaffName);
        priceItem.setCreateTime(now);
        priceItem.setUpdater(mcStaffName);
        priceItem.setUpdateTime(now);
        return priceItem;
    }

    private boolean isDataValidate(ProductTariffItemCityPriceGroupVo e) {
        return NumberUtil.isPositiveInteger(e.getPrice()) || (NumberUtil.isPositiveInteger(e.getNegotiableMaxPrice()) && NumberUtil.isPositiveInteger(e.getNegotiableMinPrice()));
    }
}
